//#pragma comment(linker, "/subsystem:windows /entry:mainCRTStartup")

#include "MyWorkQueue.h"

#include "OCMain/HttpClient.h"
#include "OCMain/Environment.h"
#include "OCMain/DynLibManager.h"
#include "OCMain/ArgumentParser.h"
#include "OCServer/Server.h"
#include "OCServer/ServerUtil.h"

Server* mServer = NULL;
Environment* mEnvironment = NULL;
DynLibManager* mDynLibManager = NULL;

#if WIN32
#include <Windows.h>

BOOL WINAPI HandlerRoutine(DWORD dwCtrlType) {

    if (CTRL_CLOSE_EVENT == dwCtrlType) {
        CORE_SAFE_DELETE(mServer);
        CORE_SAFE_DELETE(mDynLibManager);
        CORE_SAFE_DELETE(mEnvironment);
    }

    return TRUE;
}
typedef void (*DLL_START_PLUGIN)(void);
typedef void (*DLL_STOP_PLUGIN)(void);
#endif

void startup(String argv0,int port)
{
    String name, ext, path;
    StringUtil::splitFullFilename(argv0, name, ext, path);
    path = StringUtil::replaceAll(path, "\\", "/");
#if WIN32
    SetConsoleCtrlHandler(HandlerRoutine, true);
#endif
    mEnvironment = new Environment(path);
    mEnvironment->loadConfig(path + "config.ini");
    mDynLibManager = new DynLibManager();
    mServer = new Server;
    mServer->start(port);
}

//#define TEST

#ifdef TEST
void test1()
{
    //String token = "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ4eHp4LXN4a2oiLCJzdWIiOiJNVVNJQy1HUlBDIiwicm9sZXMiOiJ4eHp4LXN4a2oiLCJpc3MiOiJCZWlqaW5nJ3MgQ0lNSVNTIiwiZXhwIjoxNjI1MzExMjMyLCJpYXQiOjE2MjUyMjQ4MzJ9.nHN1VDR-nVyzvJVxnA_sufOtyGSy3_TpVzazBZGK0IE";
    Json::Value emptyValue;
    String token = ServerUtil::jwtEncode(emptyValue);
    Json::Value decodeObject = ServerUtil::jwtDecode(token);
    Json::StyledWriter writer;
    std::cout << writer.write(decodeObject) << "\n";
}

void test2()
{
    String key = "hxgis.com";
   
    String password = StringUtil::ANSIToUTF8("admin1111admin1111adminXX");

    String aseCode = ServerUtil::AES_Encode(key, password);
    String password2 = ServerUtil::AES_Decode(key, aseCode);
    std::cout << aseCode << "\n";
    std::cout << StringUtil::UTF8ToANSI(password2) << "\n";
}

void test3()
{
}

#endif

#include <iostream>
#include <chrono>
#include <ctime>

int main(int argc, char** argv)
{
#ifdef TEST
    test3();
#endif
    ArgumentParser arguments(&argc, argv);

    int port = 9023;
    arguments.read("--port", port);

#if WIN32
    bool fork = false;
    arguments.read("--fork", fork);

    if (fork)
    {
        try {
            STARTUPINFO si;
            PROCESS_INFORMATION pi;
            ZeroMemory(&si, sizeof(si));
            si.cb = sizeof(si);
            ZeroMemory(&pi, sizeof(pi));

            String applicationPath = arguments.getApplicationName();

            String argv_s = str_format("%s --port %d", applicationPath.c_str(), port);
            do {
                if (!CreateProcess((LPSTR)applicationPath.c_str(), (LPSTR)argv_s.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
                {
                    std::cout << "error:" << GetLastError() << std::endl;
                    return 0;
                }
                LOG_INFO << "working process" << pi.dwProcessId << "\n";

                WaitForSingleObject(pi.hProcess, INFINITE);
                CloseHandle(pi.hProcess);
                CloseHandle(pi.hThread);
            } while (true);
        }
        catch (...) {

        }

        exit(0);
    }
    else
    {
#endif
        startup(argv[0],port);
#if WIN32
    }
#endif

	return 0;
}

